package util;

import java.util.*;

/**
 * @author Alex Vikharev vikharev@yandex-team.ru
 *         created 11.02.12
 */
public class Bag<X> implements Iterable<X> {
    private Map<X, Integer> backingMap;

    public Bag(boolean ordered) {
        if (ordered) {
            backingMap = new TreeMap<>();
        } else {
            backingMap = new HashMap<>();
        }
    }

    public Bag() {
        this(false);
    }

    public Bag(int size) {
        backingMap = new HashMap<>(size);
    }

    public int size() {
        return backingMap.size();
    }

    public boolean contains(X arg) {
        return backingMap.containsKey(arg);
    }

    public int remove(X arg) {
        return backingMap.remove(arg);
    }

    public int put(X arg) {
        if (!backingMap.containsKey(arg)) {
            backingMap.put(arg, 1);
            return 1;
        } else {
            int count = backingMap.get(arg) + 1;
            backingMap.put(arg, count);
            return count;
        }
    }

    public int get(X arg) {
        if (!backingMap.containsKey(arg)) {
            return 0;
        } else {
            return backingMap.get(arg);
        }
    }

    public void clear() {
        backingMap.clear();
    }

    public Set<X> asSet() {
        return backingMap.keySet();
    }

    public void addAll(Iterable<X> arg) {
        for (X x : arg) {
            put(x);
        }
    }

    @Override
    public Iterator<X> iterator() {
        return backingMap.keySet().iterator();
    }

    @Override
    public String toString() {
        return backingMap.toString();
    }
}
